package com.beiding.my.dtmapping;

import org.hibernate.SessionFactory;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.persister.walking.spi.AttributeDefinition;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import java.util.HashMap;
import java.util.Map;

@Component
public class DtTypeMapperHolder {

    private EntityManager entityManager;

    public DtTypeMapperHolder(EntityManager entityManager) {
        this.entityManager = entityManager;
        try {

            //直接初始化
            init();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //be类型
    private Map<Class, DtTypeMapper> typeMapperMap = new HashMap<>();
    private Map<String, DtTypeMapper> nameMapperMap = new HashMap<>();

    //be引用
    private Map<Class, DtTypeMapper> typeQuoteMapperMap = new HashMap<>();
    private Map<String, DtTypeMapper> nameQuoteMapperMap = new HashMap<>();

    public <T> DtTypeMapper<T> getMapper(Class<T> type) {
        return typeMapperMap.get(type);
    }

    public DtTypeMapper getMapper(String name) {
        return nameMapperMap.get(name);
    }

    public DtTypeMapper getQuoteMapper(Class type) {
        return typeQuoteMapperMap.get(type);
    }

    public DtTypeMapper getQuoteMapper(String name) {
        return nameQuoteMapperMap.get(name);
    }

    private void init() throws Exception {

        EntityManagerFactory beanEntityManagerFactory = entityManager.getEntityManagerFactory();
        SessionFactoryImpl sessionFactory = (SessionFactoryImpl) beanEntityManagerFactory.unwrap(SessionFactory.class);
        MetamodelImplementor metamodelImplementor = sessionFactory.getMetamodel();
        for (EntityPersister value : metamodelImplementor.entityPersisters().values()) {
            DtTypeMapper beTypeMapper = new DtTypeMapper();
            Class aClass = value.getMappedClass();

            beTypeMapper.type = aClass;
            beTypeMapper.name = aClass.getSimpleName();
            SingleTableEntityPersister entityPersister = (SingleTableEntityPersister) value;
            beTypeMapper.tableName = entityPersister.getTableName();
            Iterable<AttributeDefinition> attributes = entityPersister.getAttributes();
            for (AttributeDefinition attr : attributes) {
                DtFieldMapper beFieldMapper = new DtFieldMapper();
                beFieldMapper.name = attr.getName(); //在entity中的属性名称
                beFieldMapper.field = aClass.getDeclaredField(beFieldMapper.name);
                beFieldMapper.field.setAccessible(true);
                String[] columnNames = entityPersister.getPropertyColumnNames(beFieldMapper.name);
                beFieldMapper.colName = columnNames[0];
                beTypeMapper.addField(beFieldMapper);

            }

            DtFieldMapper beFieldMapper = new DtFieldMapper();
            beFieldMapper.name = entityPersister.getIdentifierPropertyName();
            beFieldMapper.field = aClass.getDeclaredField(beFieldMapper.name);
            beFieldMapper.field.setAccessible(true);
            String[] columnNames = entityPersister.getIdentifierColumnNames();
            beFieldMapper.colName = columnNames[0];
            beTypeMapper.addField(beFieldMapper);


            //TODO 缺少id字段的映射内容

            if (beTypeMapper.getName().startsWith("_Quote_")) {
                Class<?> beType = Class.forName(aClass.getPackage().getName() + "." + beTypeMapper.getName().substring(7));
                typeQuoteMapperMap.put(beType, beTypeMapper);
                nameQuoteMapperMap.put(beType.getSimpleName(), beTypeMapper);
            } else {
                nameMapperMap.put(aClass.getSimpleName(), beTypeMapper);
                typeMapperMap.put(aClass, beTypeMapper);
            }
        }

    }

}
